package com.xsoft.sms.cmpp20.message.impl;

import com.xsoft.sms.cmpp20.message.ICMPP20Message;
import com.xsoft.sms.cmpp20.message.exception.CMPP20MessaageException;
import org.apache.log4j.Logger;

import java.nio.ByteBuffer;

/**
 * package: {PACKAGE_NAME}
 * User: zhanglm
 * Date: 12-9-13
 * Time: 下午4:14
 * Description:
 */
public abstract class CMPP20Message implements ICMPP20Message {

	private static Logger logger = Logger.getLogger(CMPP20Message.class);

	/**
	 * CMPP 2.0 Command_Id定义
	 */
	public static final int CMPP20_CONNECT	                    =   0x00000001;          //请求连接
	public static final int CMPP20_CONNECT_RESP	                =   0x80000001;          //请求连接应答
	public static final int CMPP20_TERMINATE	                =   0x00000002;          //终止连接
	public static final int CMPP20_TERMINATE_RESP	            =   0x80000002;          //终止连接应答
	public static final int CMPP20_SUBMIT		                =   0x00000004;          //提交短信
	public static final int CMPP20_SUBMIT_RESP	                =   0x80000004;          //提交短信应答
	public static final int CMPP20_DELIVER	                    =   0x00000005;          //短信下发
	public static final int CMPP20_DELIVER_RESP	                =   0x80000005;          //下发短信应答
	public static final int CMPP20_QUERY	                    =   0x00000006;          //发送短信状态查询
	public static final int CMPP20_QUERY_RESP	                =   0x80000006;          //发送短信状态查询应答
	public static final int CMPP20_CANCEL		                =   0x00000007;          //删除短信
	public static final int CMPP20_CANCEL_RESP	                =   0x80000007;          //删除短信应答
	public static final int CMPP20_ACTIVE_TEST	                =   0x00000008;          //激活测试
	public static final int CMPP20_ACTIVE_TEST_RESP	            =   0x80000008;          //激活测试应答
	public static final int CMPP20_FWD	                        =   0x00000009;          //消息前转
	public static final int CMPP20_FWD_RESP	                    =   0x80000009;          //消息前转应答
	public static final int CMPP20_MT_ROUTE	                    =   0x00000010;          //MT路由请求
	public static final int CMPP20_MT_ROUTE_RESP                =   0x80000010;          //MT路由请求应答
	public static final int CMPP20_MO_ROUTE	                    =   0x00000011;          //MO路由请求
	public static final int CMPP20_MO_ROUTE_RESP	            =   0x80000011;          //MO路由请求应答
	public static final int CMPP20_GET_ROUTE	                =   0x00000012;          //获取路由请求
	public static final int CMPP20_GET_ROUTE_RESP	            =   0x80000012;          //获取路由请求应答
	public static final int CMPP20_MT_ROUTE_UPDATE	            =   0x00000013;          //MT路由更新
	public static final int CMPP20_MT_ROUTE_UPDATE_RESP         =	0x80000013;          //MT路由更新应答
	public static final int CMPP20_MO_ROUTE_UPDATE              =   0x00000014;          //MO路由更新
	public static final int CMPP20_MO_ROUTE_UPDATE_RESP         =   0x80000014;          //MO路由更新应答
	public static final int CMPP20_PUSH_MT_ROUTE_UPDATE         =   0x00000015;          //MT路由更新
	public static final int CMPP20_PUSH_MT_ROUTE_UPDATE_RESP    =   0x80000015;          //MT路由更新应答
	public static final int CMPP20_PUSH_MO_ROUTE_UPDATE         =   0x00000016;          //MO路由更新
	public static final int CMPP20_PUSH_MO_ROUTE_UPDATE_RESP    =	0x80000016;          //MO路由更新应答


	public static final int CMPP20_HEAD_LENGTH                  =   12;

	/**
	 * 信息格式
		 0：ASCII串
		 3：短信写卡操作
		 4：二进制信息
		 8：UCS2编码
		 15：含GB汉字
	 */
	public static final byte CMPP20_MSG_FMT_ASCII       =   0x00;
	public static final byte CMPP20_MSG_FMT_SIM         =   0x03;
	public static final byte CMPP20_MSG_FMT_BINARY      =   0x04;
	public static final byte CMPP20_MSG_FMT_UCS2        =   0x08;
	public static final byte CMPP20_DEFAULT_MSG_GBHZ    =   0x0F;
	public static final byte CMPP20_DEFAULT_MSG_FMT     =   CMPP20_DEFAULT_MSG_GBHZ;


	public static final byte CMPP20_VERSION             =   0x20;


	protected CMPP20MessageHead head;
	protected ICMPP20Message body;

	protected CMPP20Message(CMPP20MessageHead head, ICMPP20Message body) {
		this.head = head;
		this.body = body;
	}

	protected CMPP20Message() {
	}

	@Override
	public byte[] toBuffer() {
		byte[] headBuffer = head.toBuffer();
		byte[] bodyBuffer = body.toBuffer();
		ByteBuffer buffer = ByteBuffer.allocate(headBuffer.length + bodyBuffer.length);
		buffer.put(headBuffer);
		buffer.put(bodyBuffer);
		return buffer.array();
	}

	@Override
	public void fromBuffer(byte[] buffer) throws CMPP20MessaageException {
		ByteBuffer headBuffer = ByteBuffer.wrap(buffer, 0, CMPP20_HEAD_LENGTH);
		ByteBuffer bodyBuffer = ByteBuffer.wrap(buffer, CMPP20_HEAD_LENGTH, buffer.length - CMPP20_HEAD_LENGTH);

		try {
			head.fromBuffer(headBuffer.array());
		} catch (Exception ex) {
			logger.error(ex.getMessage());
			throw new CMPP20MessaageException("消息头数据解析错误");
		}

		try  {
			body.fromBuffer(bodyBuffer.array());
		} catch (Exception ex) {
			logger.error(ex.getMessage());
			throw new CMPP20MessaageException("消息体数据解析错误");
		}
	}

	public CMPP20MessageHead getHead() {
		return head;
	}

	public void setHead(CMPP20MessageHead head) {
		this.head = head;
	}

	public ICMPP20Message getBody() {
		return body;
	}

	public void setBody(ICMPP20Message body) {
		this.body = body;
	}

	public int getCmdId() {
		return ((CMPP20MessageHead)head).getCmdId();
	}
}
